package engine.systems.input.interaction
{
	import engine.classes.enumerations.SystemPriority;
	import engine.systems.update.GameSystem;
	
	import flash.display.DisplayObjectContainer;
	
	/**
	 * Will need to revisit this. It's not as clean is it should be...
	 */
	public class InteractionSystem extends GameSystem
	{
		
		public function InteractionSystem()
		{
			super(InteractionNode, updateNode, nodeAdded, nodeRemoved);
			
			this.priority = SystemPriority.UPDATE;
		}
		
		public function updateNode(node:InteractionNode, time:Number):void
		{
			var interaction:Interaction = node.interaction;
			
			if(interaction.locked) return;
			
			if(interaction._invalidate)
			{
				interaction._invalidate = false;
				
				if(interaction._clickActive || interaction._clickActivate)
				{
					interaction._clickActive = interaction._clickActivate;
					if(interaction._clickActivate)
					{
						interaction._clickActivate = false;
						interaction.click.dispatch(node.entity, interaction._clickEvent);
					}
					else interaction._clickEvent = null;
				}
				
				if(interaction._upActive || interaction._upActivate)
				{
					interaction._upActive = interaction._upActivate;
					if(interaction._upActivate)
					{
						interaction._upActivate = false;
						interaction.up.dispatch(node.entity, interaction._upEvent);
					}
					else interaction._upEvent = null;
				}
				
				if(interaction._downActive || interaction._downActivate)
				{
					interaction._downActive = interaction._downActivate;
					if(interaction._downActivate)
					{
						interaction._downActivate = false;
						interaction.down.dispatch(node.entity, interaction._downEvent);
					}
					else interaction._downEvent = null;
				}
				
				if(interaction._overActive || interaction._overActivate)
				{
					interaction._overActive = interaction._overActivate;
					if(interaction._overActivate)
					{
						interaction._overActivate = false;
						interaction.over.dispatch(node.entity, interaction._overEvent);
					}
					else interaction._overEvent = null;
				}
				
				if(interaction._outActive || interaction._outActivate)
				{
					interaction._outActive = interaction._outActivate;
					if(interaction._outActivate)
					{
						interaction._outActivate = false;
						interaction.out.dispatch(node.entity, interaction._outEvent);
					}
					else interaction._outEvent = null;
				}
				
				/*if(interaction._releaseActive || interaction._releaseActivate)
				{
					interaction._releaseActive = interaction._releaseActivate;
					if(interaction._releaseActivate)
					{
						interaction._releaseActivate = false;
						interaction.release.dispatch(node.entity, interaction._releaseEvent);
					}
					else interaction._releaseEvent = null;
				}*/
			}
			
			if(interaction._updateInteractions) this.updateInteractions(node);
		}
		
		private function updateInteractions(node:InteractionNode):void
		{
			var display:DisplayObjectContainer 	= node.render.display as DisplayObjectContainer;
			display.mouseEnabled 				= true;
			var interaction:Interaction 		= node.interaction;
			var action:String;
			var native:String;
			
			for each(action in Interaction.TYPES)
			{
				native = "_" + action + "Native";
				if(interaction[native])
				{
					interaction[native].removeAll();
					interaction[native] = null;
				}
			}
			
			for each(action in interaction._interactions)
			{
				native = "_" + action + "Native";
				interaction[native] = Interaction.createNativeSignal(display, action);
				interaction[native].add(interaction[action + "Handler"]);
			}
			
			interaction._updateInteractions = false;
		}
		
		private function nodeAdded(node:InteractionNode):void
		{
			DisplayObjectContainer(node.render.display).mouseEnabled = true;
			node.render.changed.add(node.interaction.displayChanged);
			
			this.updateInteractions(node);
		}
		
		private function nodeRemoved(node:InteractionNode):void
		{
			DisplayObjectContainer(node.render.display).mouseEnabled = false;
			
			var interaction:Interaction = node.interaction;
			
			interaction.click.removeAll();
			interaction.up.removeAll();
			interaction.down.removeAll();
			interaction.over.removeAll();
			interaction.out.removeAll();
			
			if(interaction._clickNative) 	{ interaction._clickNative.removeAll(); interaction._clickNative 	= null; }
			if(interaction._upNative) 		{ interaction._upNative.removeAll(); 	interaction._upNative 		= null; }
			if(interaction._downNative) 	{ interaction._downNative.removeAll(); 	interaction._downNative 	= null; }
			if(interaction._overNative) 	{ interaction._overNative.removeAll(); 	interaction._overNative 	= null; }
			if(interaction._outNative) 		{ interaction._outNative.removeAll(); 	interaction._outNative 		= null; }
			
			interaction._clickEvent = null;
			interaction._upEvent 	= null;
			interaction._downEvent 	= null;
			interaction._overEvent	= null;
			interaction._outEvent 	= null;
		}
	}
}